/*
* 二进制与十进制的转换
*   二的10转十的10：1010 -> 10 每一位×2的对应次方并相加
*   1        0        1        0
*   1*2**3 + 0*2**2 + 1*2**1 + 0*2**0 = 8 + 0 + 2 + 0 = 10
*
*   十的10转二的10：每次除以2，得出结果，并记下余数，再用结果去除以2，记下余数，依次循环，直到结果为零，最后将余数倒着拼接
*   10/2=5 余数为0
*   5/2=2 余数为1
*   2/2=1 余数为0
*   1/2=0 余数为1
*   则得出1010
*
* */
class Stack{
    constructor(){
        this.count = 0 //栈的计数器
        this.items = {} //栈的数据仓库
    }
    push(...eles){ //添加一个值
        for(let i = 0,len = eles.length; i < len; i++){
            this.items[this.count] = eles[i] //采用计数器当前值（自然数）为下标key，存储实际数据
            this.count++ //每次push进一个数据，计数器自增1
        }
    }
    size(){ //返回栈的长度
        return this.count //每次查询的时候直接返回当前的计数器的值
    }
    isEmpty(){ //判断栈是否为空
        return !this.count //判断是否为空，直接返回计数器的取反，0取反为true，大于零取反为false
    }
    pop(){ //删除栈顶值并返回被删除的值
        if(this.isEmpty()){ //先进行判断，如果栈内为空，直接返回undefined
            return undefined
        }

        //如果不走上面的if判断则表明栈非空，那么就走下面的代码
        this.count-- //先进行计数器自减1，减去1之后得到的就是未删除前栈顶值的下标key，如果不明白，用几个数代入就知道了
        let result = this.items[this.count] //得到栈顶的值
        delete this.items[this.count] //删除栈顶的值
        return result //并返回被删除的栈顶的值
    }
    peek(){ //返回栈顶的值不对栈做任何修改
        if(this.isEmpty()){ //先进行判断，如果栈内为空，直接返回undefined
            return undefined
        }
        return this.items[this.count - 1] //否则返回当前的栈顶值
    }
    clear(){ //清空栈内数据
        while(!this.isEmpty()){ //当栈内为非空则一直进行这个循环，pop删除直到栈内没有数据为止
            this.pop()
        }
    }
    toString(){ //转字符串
        if(this.isEmpty()){ //先进行判断，如果栈内为空，直接返回空字符串""
            return ""
        }
        let resultString = "" //如果非空则先用一个变量保存，因为我们也不知道有多少个值，默认为空字符串
        for(let i = 0; i < this.count; i++){
            resultString = `${resultString},${this.items[i]}` //如果无法理解，代入几个数进去即可明白
        }
        return resultString.slice(1) //因为上面的模板字符串拼接方式会在第一位返回多一个逗号，所以要用slice方法删除逗号
    }
    forEach(cb){ //forEach方法接收一个回调函数
        for(let i = 0; i < this.count; i++){
            cb(i,this.items[i],this) //回调函数接收三个参数index，items，arr本身
        }
    }
    [Symbol.iterator](){ //手动添加一个迭代器接口
        let self = this //先保存好当前的this
        let index = 0 //定义一个索引
        return {
            next(){
                if(index < self.count){ //如果没有遍历结束，则一个个返回当前值
                    return {
                        value:self.items[index++], //运用了闭包
                        done:false //false表示没有遍历完成
                    }
                }else{ //否则如果变量结束，则返回undefined
                    return {
                        value:undefined,
                        done:true //true表示遍历结束
                    }
                }
            }
        }
    }
}

let arr = new Stack()
//用我们刚刚的栈

function decimalToBinary(decNumber){ //十进制转二进制接收一个十进制参数
    let remStack = new Stack() //存储余数的数组
    let number = decNumber //存储传输进来的十进制参数
    let rem //余数
    let binaryString = "" //存储转换后的二进制数据字符串
    while(number>0){ //当十进制数字非零时，循环以下操作
        rem = Math.floor(number % 2) //取余数
        remStack.push(rem) //把余数添加到栈里面
        number = Math.floor(number / 2) //得到新的十进制数字，向下取整，不要余数
    }
    while(!remStack.isEmpty()){ //当栈内还有数据时，循环以下操作
        binaryString += remStack.pop().toString() //取出余数，并进行组合成字符串拼接
    }
    return binaryString*1 //乘1将字符串转换成数字，我自己加的这一步
}

decimalToBinary(100)